package CS4310.csueb.visual;
///////////////////////////////////////////////////////////////////////////
//class MapTile 
//
//    The game map will use game tiles which allow 
//
//      1.  Game Space expansion at future dates or during development
//      2.  Localized qualities such as harm, protection, no-access, etc.
//      3.  Localized placement of items that can be found or dropped
//      4.  Movement based on transitions from tile to tile.
//      5.  Scrollable Map Characteristics similar to Google maps
//      6.  Vertical Levels abstraction
//      7.  Simplified methods to define collisions and other interactions
//      8.  Special characteristics of localized game space not yet visioned
//
//    @author Brian L. Donat
//    Created 2011-11-05
//    Updated 2011-11-12 by Brian to add multi-directional access qualities.
//    Updated 2011-11-29 by Brian to modify setQuality to take a String param
//
///////////////////////////////////////////////////////////////////////////


import java.util.ArrayList; 

import CS4310.csueb.items.Armor;
import CS4310.csueb.items.Food;
import CS4310.csueb.items.Item;
import CS4310.csueb.items.KeyItem;
import CS4310.csueb.items.Shoe;
import CS4310.csueb.items.Weapon;

///////////////////////////// class maps /////////////////////////////////
public class MapTile 
{

  // Tile Location
  //    Tile at offsetX = 0 and offsetY = 0 is the origin or gamespace center
  //    All other tiles are relative to the origin 
  //      This allows the game to grow outward in the future.
  //    It is possible to move the origin off the map
  //    The upper left corner map tile must be used to align all others. 
  private int offsetX;
  private int offsetY;

  // Tile Image
  String imageFile;

  // Tile Visibility
  boolean visible;

  // MapTile Qualities
  private enum tileQuality {
    NORMAL, HARMFUL, PROTECTED, DELAY, NOACCESS, 
    NORTHACCESS, NEACCESS, EASTACCESS, SEACCESS, SOUTHACCESS, SWACCESS, WESTACCESS, NWACCESS
  }

  // Current Tile Quality, NORMAL by default 
  tileQuality quality;

  // If this tile has multiple levels, maxLevels > 0
  //    and items can be placed on levels
  //        occupant can move between levels
  private static final int LEVELMAX = 4;  // Absolute Max for this any tile.
  private int maxLevels;

  // Current Occupant of the Tile ( if any )
  //   Can be Boss, Hero or Enemy
  private CharacterSprite occupant;
  private int o_level;
  boolean occupied;

  // items that may found in this tile 
  //    ( can be more than one of a type )
  private ArrayList<Weapon> weapons;
  private ArrayList<Armor> armor;
  private ArrayList<Shoe> shoes;
  private ArrayList<Food> food;
  private ArrayList<KeyItem> keyItems;

  private ArrayList<Integer> wlevel;
  private ArrayList<Integer> alevel;
  private ArrayList<Integer> slevel;
  private ArrayList<Integer> flevel;
  private ArrayList<Integer> klevel;

//--------------------------------------------------------//
  
//********* default constructor **********//  
  public MapTile() 
  {
      quality = tileQuality.NORMAL;
      occupied = false;
      visible = false;
      o_level = 0;
  }

//******* overloaded constructor *********//
//takes a file name for an image and map dimensions   
  public MapTile(String filename) 
  {
      this();
          
      quality = tileQuality.NORMAL;
      occupied = false;
      visible = false;
      o_level = 0;
      imageFile = filename;
  }


//-- Setters --//

//********* set Location **********//  
//  Location is relative to origin(0,0) and so x and y can be negative.
  public void setLocation(int x, int y) 
  {   
	  offsetX = x;
	  offsetY = y;
  }

//********* set x Offset **********//  
//  Location is relative to origin(0,0) and so x can be negative.
  public void setX(int x) 
  {   
	  offsetX = x;
  }

//********* set y Offset **********//  
//  Location is relative to origin(0,0) and so y can be negative.
  public void setY(int y) 
  {   
	  offsetY = y;
  }

//******* set Tile Image *********//
//takes a file name for an image   
  public void setTileImage(String filename) 
  {
      imageFile = filename;
  }

//******* set Visibility *********// 
  public void setVisibility(boolean v) 
  {
      visible = v;
  }

//******* set Quality *********// 
  public void setQuality(String q) 
  {
	  if ( q == "NORMAL" ) quality = tileQuality.NORMAL;
	  if ( q == "HARMFUL" ) quality = tileQuality.HARMFUL;
	  if ( q == "PROTECTED" ) quality = tileQuality.PROTECTED;
	  if ( q == "DELAY" ) quality = tileQuality.DELAY;
	  if ( q == "NOACCESS" ) quality = tileQuality.NOACCESS;
	  
	  if ( q == "NORTHACCESS" ) quality = tileQuality.NORTHACCESS;
	  if ( q == "NEACCESS" ) quality = tileQuality.NEACCESS;
	  if ( q == "EASTACCESS" ) quality = tileQuality.EASTACCESS;
	  if ( q == "SEACCESS" ) quality = tileQuality.SEACCESS;
	  if ( q == "SOUTHACCESS" ) quality = tileQuality.SOUTHACCESS;
	  if ( q == "SWACCESS" ) quality = tileQuality.SWACCESS;
	  if ( q == "WESTACCESS" ) quality = tileQuality.WESTACCESS;
	  if ( q == "NWACCESS" ) quality = tileQuality.NWACCESS;
  }

//********* set Max Levels **********//  
//    If an attempt is made to exceed LEVELSMAX, maxLevels = 0 w/o complaint
  public void setMaxLevels(int max) 
  {   
      if ( max > LEVELMAX ) max = 0;
      maxLevels = max;
  }
  
//********* increment Level **********//  
//Do not exceed maxLevels
public void incrLevel() 
{   
    if ( o_level < maxLevels ) o_level++;
}

//********* decrement Level **********//  
//Do not go below level 0
public void decrLevel() 
{   
    if ( o_level > 0 ) o_level--;
}

//********* add Occupant w. level **********//  
  public boolean addOccupant(CharacterSprite o, int level) 
  {   
      boolean success = true;

      if ( quality == tileQuality.NOACCESS || occupied ) {
          success = false;
      }
      else {
          if ( level > maxLevels ) level = 0;
          o_level = level;
          occupant = o;
          occupied = true;
      }
      return success;
  }

//********* add Occupant **********//  
  public boolean addOccupant(CharacterSprite o) 
  {   
      boolean success = true;

      if ( quality == tileQuality.NOACCESS || occupied ) {
          success = false;
      }
      else {
          occupant = o;
          occupied = true;
      }
      return success;
  }

//********* add Item **********//  
  public void addItem(Item i, int level) 
  {   
	  if ( level > maxLevels ) level = 0;

	  if ( i instanceof Weapon ) addWeapon((Weapon) i, level);
	  else if ( i instanceof Armor ) addArmor((Armor) i, level);
	  else if ( i instanceof Shoe ) addShoe((Shoe) i, level);
	  else if ( i instanceof Food ) addFood((Food) i, level);
	  else if ( i instanceof KeyItem ) addKeyItem((KeyItem) i, level);
  }

//********* add Weapon **********//  
  public void addWeapon(Item i, int level) 
  {   
	  if ( level > maxLevels ) level = 0;

	  weapons.add((Weapon) i);
          wlevel.add(level);
  }

//********* add Armor **********//  
  public void addArmor(Item i, int level) 
  {   
	  if ( level > maxLevels ) level = 0;

	  armor.add((Armor) i);
          alevel.add(level);
  }

//********* add Shoe **********//  
  public void addShoe(Item i, int level) 
  {   
	  if ( level > maxLevels ) level = 0;

	  shoes.add((Shoe) i);
          slevel.add(level);
  }

//********* add Food **********//  
  public void addFood(Item i, int level) 
  {   
	  if ( level > maxLevels ) level = 0;

	  food.add((Food) i);
          flevel.add(level);
  }

//********* add KeyItem **********//  
  public void addKeyItem(Item i, int level) 
  {   
	  if ( level > maxLevels ) level = 0;

	  keyItems.add((KeyItem) i);
          klevel.add(level);
  }


//-- getters --//

//********* get x Offset **********//  
//  Location is relative to origin(0,0) and so x can be negative.
  public int getX() 
  {   
	  return offsetX;
  }

//********* get y Offset **********//  
//  Location is relative to origin(0,0) and so y can be negative.
  public int getY() 
  {   
	  return offsetY;
  }

//******* get Tile Image *********//
//takes a file name for an image   
  public String getTileImage() 
  {
      return imageFile;
  }

//******* is Visible *********// 
  public boolean isVisible() 
  {
      return visible;
  }

//******* get Quality *********// 
  public tileQuality setQuality() 
  {
      return quality;
  }

//********* get Max Levels **********//  
  public int getMaxLevels() 
  {   
	  return maxLevels;
  }

//********* get Occupant w/o removing **********//
//  Allow testing and manipulating Occupant Type while resident in tile
  public CharacterSprite getOccupant() 
  {   
       return occupant;
  }

//********* remove Occupant **********//  
  public CharacterSprite removeOccupant() 
  {   
      CharacterSprite o = occupant;
      occupant = null;
      o_level = 0;
      occupied = false;
      return o;
  }

//********* get WeaponsList **********//  
  public ArrayList<Weapon> getWeaponsList() 
  {   
	  return weapons;
}

//********* get ArmorLevelList **********//  
  public ArrayList<Integer> getWeaponsLevelList() 
  {   
	  return wlevel;
  }

//********* get ArmorList **********//  
  public ArrayList<Armor> getArmorList() 
  {   
	  return armor;
  }

//********* get ArmorLevelList **********//  
  public ArrayList<Integer> getArmorLevelList() 
  {   
	  return alevel;
  }

//********* get ShoeList **********//  
  public ArrayList<Shoe> getShoeList() 
  {   
	  return shoes;
  }

//********* get ArmorLevelList **********//  
  public ArrayList<Integer> getShoeLevelList() 
  {   
	  return slevel;
  }

//********* get FoodList **********//  
  public ArrayList<Food> getFoodList() 
  {   
	  return food;
  }

//********* get ArmorLevelList **********//  
  public ArrayList<Integer> getFoodLevelList() 
  {   
	  return flevel;
  }

//********* get KeyItemList **********//  
  public ArrayList<KeyItem> getKeyItemList() 
  {   
	  return keyItems;
  }

//********* get KeyItemLevelList **********//  
  public ArrayList<Integer> getKeyItemLevelList() 
  {   
	  return klevel;
  }

}

